<?php


namespace app\api\service;


use app\lib\enum\ScopeEnum;
use app\lib\exception\ForbiddenException;
use app\lib\exception\TokenException;
use think\Cache;
use think\Exception;
use think\Request;

class BaseToken
{
    // 生成token规则
    public static function generateToken()
    {
        // 32个字符组成一组随机字符串
        $randChars = getRandChars(32);
        // 时间戳
        $timestamp = $_SERVER['REQUEST_TIME_FLOAT'];
        // 盐
        $salt = config('secure.token_salt');

        // 三组字符串进行md5加密返回
        return md5($randChars.$timestamp.$salt);
    }

    // 通用方法获取缓存里的value
    public static function getCurrentToken($key)
    {
        // 从HTTP请求的header里获取用户token
        $token = Request::instance()->header('token');
        // 从缓存里读取键
        $vars = Cache::get($token);
        if (!$vars) {
            throw new TokenException();
        } else {
            if (!is_array($vars)) {
                $vars = json_decode($vars, true);
            }
            if (array_key_exists($key, $vars)) {
                return $vars[$key];
            } else {
                throw new Exception('要获取的token变量不存在');
            }
        }
    }

    // 从缓存里根据token获取当前uid
    public static function getCurrentUid()
    {
        $uid = self::getCurrentToken('uid');
        return $uid;
    }

    // 封装scope权限验证
    public static function needScope()
    {
        $scope = self::getCurrentToken('scope');
        if ($scope) {
            if ($scope == ScopeEnum::User) {
                return true;
            } else {
                throw new ForbiddenException();
            }
        } else {
            throw new TokenException();
        }
    }

    // 检测被检测的用户uid和令牌里的是否为同一个
    public static function isValid($checkedUID)
    {
        if (!$checkedUID) {
            throw new Exception('检测uid时必须传入一个被检测uid');
        }
        $currentUID = self::getCurrentUid();
        if ($currentUID = $checkedUID) {
            return true;
        }
        return false;
    }
}